package com.lantosec.hmrp.modules.workflow.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lantosec.hmrp.core.exception.AppException;
import com.lantosec.hmrp.core.kit.PageVO;
import com.lantosec.hmrp.core.kit.Result;
import com.lantosec.hmrp.core.kit.ResultEnum;
import com.lantosec.hmrp.core.util.BeanUtils;
import com.lantosec.hmrp.core.util.FlowableUtils;
import com.lantosec.hmrp.modules.form.entity.FormTempData;
import com.lantosec.hmrp.modules.form.service.IFormService;
import com.lantosec.hmrp.modules.form.service.IFormTempDataService;
import com.lantosec.hmrp.modules.form.vo.FormVO;
import com.lantosec.hmrp.modules.sysdata.entity.*;
import com.lantosec.hmrp.modules.sysdata.service.*;
import com.lantosec.hmrp.modules.sysdata.vo.SysDataProcessTaskVO;
import com.lantosec.hmrp.modules.system.entity.SysUser;
import com.lantosec.hmrp.modules.system.service.ISysUserService;
import com.lantosec.hmrp.modules.system.service.ISysWorkdayService;
import com.lantosec.hmrp.modules.uploads.service.ISysUploadsService;
import com.lantosec.hmrp.modules.workflow.mapper.RepositoryMapper;
import com.lantosec.hmrp.modules.workflow.service.IWorkflowQueryService;
import com.lantosec.hmrp.modules.workflow.service.IWorkflowRepositoryService;
import com.lantosec.hmrp.modules.workflow.vo.*;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.*;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 工作流查询服务
 */
@Service
@Primary
@Log4j2
public class WorkflowQueryServiceImpl implements IWorkflowQueryService {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private IFormService formService;

    @Autowired
    private IWorkflowRepositoryService workflowRepositoryService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    ProcessEngineConfiguration processEngineConfiguration;

    @Autowired
    ISysUserService sysUserService;

    @Autowired
    ISysWorkdayService workdayService;

    @Autowired
    ISysDataProcessService sysDataProcessService;

    @Autowired
    ISysDataProcessTaskService sysDataProcessTaskService;

    @Autowired
    IFormTempDataService formTempDataService;

    @Autowired
    RepositoryMapper repositoryMapper;

    @Autowired
    ISysProcessNotifyService sysProcessNotifyService;

    @Autowired
    ISysUploadsService iSysUploadsService;

    @Autowired
    ISysProcessFormService sysProcessFormService;

    @Autowired
    ISysProcessPublicityService sysProcessPublicityService;

    @Override
    public Result<ProcessInfoVO> getProcessInfo(QueryProcessVO condition) {
        ProcessInfoVO processInfoVO = new ProcessInfoVO();
        // 公示/转发(知会)
        if (StringUtils.isNotEmpty(condition.getProInsId()) && StringUtils.isNotEmpty(condition.getLayoutId())) {
            processInfoVO = getProcessInfo(condition.getProInsId(), condition.getLayoutId());
            return Result.ok(processInfoVO);
        }
        String layoutId = "";
        String businessKey = "";
        String processDefinitionId = condition.getProcdefId();
        if (StringUtils.isBlank(processDefinitionId)) {
            return Result.fail("参数错误，缺少流程定义Id");
        }
        SysProcessForm processForm = sysProcessFormService.selectByDefinitionId(processDefinitionId);
        if (Objects.isNull(processForm)) {
            return Result.fail("参数错误，该流程不存在");
        }
        processInfoVO.setProcessName(processForm.getProcessName());

        //获取流程图
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        String userTaskId = "";
        String taskId = condition.getTaskId();
        String userId = condition.getUserId();
        if (StringUtils.isNotBlank(taskId)) {
            // 根据任务节点Id获取信息，流程已启动
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            if (!Objects.isNull(task)) {
                userTaskId = task.getTaskDefinitionKey();
                FlowTaskVO flowTaskVO = new FlowTaskVO(task);
                processInfoVO.setFlowTask(flowTaskVO);

                // 查询流程获取业务数据的key
                ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
                businessKey = processInstance.getBusinessKey();
                processInfoVO.setFormDataId(businessKey);
                processInfoVO.setProInsName(processInstance.getName());

                // 更新查看时间
                sysDataProcessTaskService.updateLookTime(userId, taskId);
            } else {
                // 从历史数据中查询
                HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
                if (!Objects.isNull(historicTaskInstance)) {
                    userTaskId = historicTaskInstance.getTaskDefinitionKey();
                    FlowTaskVO flowTaskVO = new FlowTaskVO(historicTaskInstance);
                    processInfoVO.setFlowTask(flowTaskVO);

                    String processInstanceId = historicTaskInstance.getProcessInstanceId();
                    HistoricProcessInstance hisProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
                    businessKey = hisProcessInstance.getBusinessKey();
                    processInfoVO.setFormDataId(businessKey);
                    processInfoVO.setProInsName(hisProcessInstance.getName());
                }
            }
        } else {
            userTaskId = FlowableUtils.getFirstUserTaskId(bpmnModel);
        }
        // 查询任务节点自定义属性
        CustomAttributeVO customAttributeVO = workflowRepositoryService.getCustomAttribute(userTaskId, bpmnModel);
        if (!Objects.isNull(customAttributeVO)) {
            layoutId = customAttributeVO.getFormLayoutId();
        }
        processInfoVO.setCustomAttribute(customAttributeVO);
        // 查询业务数据和表单布局信息
        Result<FormVO> formResult = formService.queryDataByFormId(layoutId, businessKey);
        if (ResultEnum.SUCCESS.code.equals(formResult.getState())) {
            FormVO formVO = formResult.getData();
            processInfoVO.setFormData(formVO.getFormData());
            processInfoVO.setFormLayout(formVO.getFormLayout());
        }

        // 如果有临时数据,覆盖正式数据
        FormTempData dbData = formTempDataService.getOne(new QueryWrapper<FormTempData>()
                .eq(String.valueOf(FormTempData.ColName.user_id), userId)
                .eq(String.valueOf(FormTempData.ColName.task_id), taskId)
        );
        if (!Objects.isNull(dbData)) {
            JSONObject jsonObject = JSONObject.parseObject(dbData.getFormData());
            processInfoVO.setFormData(jsonObject);
            processInfoVO.setAuditStatus(dbData.getAuditStatus());
            processInfoVO.setComment(dbData.getComment());
        }

        return Result.ok(processInfoVO);
    }

    /**
     * 流程信息
     *
     * @param processInstanceId 流程实例Id
     * @param layoutId          流程布局Id
     */
    private ProcessInfoVO getProcessInfo(String processInstanceId, String layoutId) {
        ProcessInfoVO processInfoVO = new ProcessInfoVO();
        String businessKey = "";
        // 流程信息
        SysDataProcess sysDataProcess = sysDataProcessService.getBaseMapper().selectOne(new QueryWrapper<SysDataProcess>()
                .eq(String.valueOf(SysDataProcess.ColName.pro_ins_id), processInstanceId));
        if (Objects.isNull(sysDataProcess)) {
            throw new AppException("没有查询到该流程实例");
        }
        businessKey = sysDataProcess.getDataId();
        processInfoVO.setFormDataId(businessKey);
        processInfoVO.setProInsName(sysDataProcess.getProInsName());

        // 查询业务数据和表单布局信息
        Result<FormVO> formResult = formService.queryDataByFormId(layoutId, businessKey);
        if (ResultEnum.SUCCESS.code.equals(formResult.getState())) {
            FormVO formVO = formResult.getData();
            processInfoVO.setFormData(formVO.getFormData());
            processInfoVO.setFormLayout(formVO.getFormLayout());
        }

        return processInfoVO;
    }

    /**
     * 获取流程变量
     *
     * @param taskId 任务ID
     * @param key    键
     * @return
     */
    @Override
    public Object getVariablesByTaskIdAsMap(String taskId, String key) {
        return taskService.getVariable(taskId, key);
    }

    @Override
    public Result<Page<FlowTaskVO>> queryTodoTask(PageVO page, String userId) {
        int pageNo = page.getPageNo().intValue();
        int pageSize = page.getPageSize().intValue();
        int startIndex = pageNo > 1 ? (pageNo - 1) * pageSize : 0;
        List<Task> list = taskService.createTaskQuery().taskCandidateOrAssigned(userId).orderByTaskCreateTime().desc().listPage(startIndex, pageSize);
        long count = taskService.createTaskQuery().taskCandidateOrAssigned(userId).count();
        long pages = (pageNo + pageSize - 1) / pageSize;

        List<FlowTaskVO> taskVOList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            List<String> proInsIdList = list.stream().map(Task::getProcessInstanceId).collect(Collectors.toList());
            List<SysDataProcess> dataProcessList = sysDataProcessService.getBaseMapper()
                    .selectList(new QueryWrapper<SysDataProcess>().in(String.valueOf(SysDataProcess.ColName.pro_ins_id), proInsIdList));

            List<String> taskIdList = list.stream().map(Task::getId).collect(Collectors.toList());
            List<SysDataProcessTask> dataProcessTaskList = sysDataProcessTaskService.getBaseMapper()
                    .selectList(new QueryWrapper<SysDataProcessTask>().in(String.valueOf(SysDataProcessTask.ColName.task_id), taskIdList));

            list.forEach(item -> {
                FlowTaskVO flowTaskVO = new FlowTaskVO(item);

                String proInsName = dataProcessList.stream().filter(a -> a.getProInsId().equals(item.getProcessInstanceId())).findFirst()
                        .orElse(new SysDataProcess()).getProInsName();
                flowTaskVO.setProcessName(proInsName);

                Date lookTime = dataProcessTaskList.stream().filter(a -> a.getTaskId().equals(item.getId())).findFirst()
                        .orElse(new SysDataProcessTask()).getLookTime();
                flowTaskVO.setLookTime(lookTime);

                taskVOList.add(flowTaskVO);
            });
        }
        page.setRecords(taskVOList);
        page.setTotalCount(count);
        page.setTotal(count);
        page.setPages(pages);
        return Result.ok(page);
    }

    @Override
    public long countTodoTask(String userId) {
        return taskService.createTaskQuery().taskCandidateOrAssigned(userId).count();
    }

    @Override
    public Result<Page<FlowTaskVO>> queryHisTaskInstanceByUserId(PageVO page, String userId) {
        int pageNo = page.getPageNo().intValue();
        int pageSize = page.getPageSize().intValue();
        int startIndex = pageNo > 1 ? (pageNo - 1) * pageSize : 0;
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(userId)//.finished()
                .orderByTaskCreateTime().desc()
                .listPage(startIndex, pageSize);// 返回带分页的结果集合
        long count = historyService.createHistoricTaskInstanceQuery().taskAssignee(userId).count();
        long pages = (pageNo + pageSize - 1) / pageSize;

        List<FlowTaskVO> taskVOList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            List<String> proInsIdList = list.stream().map(HistoricTaskInstance::getProcessInstanceId).collect(Collectors.toList());
            List<SysDataProcess> dataProcessList = sysDataProcessService.getBaseMapper()
                    .selectList(new QueryWrapper<SysDataProcess>().in(String.valueOf(SysDataProcess.ColName.pro_ins_id), proInsIdList));
            list.forEach(item -> {
                FlowTaskVO flowTaskVO = new FlowTaskVO();
                flowTaskVO.setTaskName(item.getName());
                flowTaskVO.setProcessInstanceId(item.getProcessInstanceId());
                flowTaskVO.setProcessDefinitionId(item.getProcessDefinitionId());
                flowTaskVO.setAssignee(item.getAssignee());
                flowTaskVO.setCreateTime(item.getCreateTime());
                flowTaskVO.setTaskId(item.getId());

                String proInsName = dataProcessList.stream().filter(a -> a.getProInsId().equals(item.getProcessInstanceId())).findFirst()
                        .orElse(new SysDataProcess()).getProInsName();
                flowTaskVO.setProcessName(proInsName);

                taskVOList.add(flowTaskVO);
            });
        }
        page.setRecords(taskVOList);
        page.setTotalCount(count);
        page.setTotal(count);
        page.setPages(pages);
        return Result.ok(page);
    }

    @Override
    public Result<Page<HisProcessInstanceVO>> queryStartProInstanceByUserId(PageVO page, String userId) {
        Page<SysDataProcess> pageResult = sysDataProcessService.selectByStartUserId(page, userId);
        List<SysDataProcess> list = pageResult.getRecords();
        List<HisProcessInstanceVO> hisVOList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (SysDataProcess item : list) {
                hisVOList.add(new HisProcessInstanceVO(item));
            }
        }
        page.setRecords(hisVOList);
        return Result.ok(page);

        /*List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery()
                .startedBy(userId)//.finished()
                .orderByProcessInstanceStartTime().desc()
                .list();

        List<HisProcessInstanceVO> hisVOList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (HistoricProcessInstance item : list) {
                item.getStartUserId();
                item.getSuperProcessInstanceId();
                hisVOList.add(new HisProcessInstanceVO(item));
            }
        }
        return Result.ok(hisVOList);
*/
        /*List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(userId).finished().list();*/

        /*List<FlowTaskVO> taskVOList = new ArrayList<>();//hisProInstance.get(0).getName()
        if(CollectionUtils.isNotEmpty(list)){
            list.forEach(item-> {
                FlowTaskVO flowTaskVO = new FlowTaskVO(item);
                // 根据流程实例id获取流程实例
                ProcessInstance pi = runtimeService.createProcessInstanceQuery()
                        .processInstanceId(item.getProcessInstanceId())
                        .singleResult();
                flowTaskVO.setProcessName(pi.getName());
                taskVOList.add(flowTaskVO);
            });
        }*/
        //return Result.ok(taskVOList);
    }

    @Override
    public Result<List<HisActivityInstanceVO>> queryHisActivityInstance(String processInstanceId) {
        List<HistoricActivityInstance> list = historyService
                .createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId)
                .finished()
                .list();

        List<HisActivityInstanceVO> hisVOList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (HistoricActivityInstance item : list) {
                hisVOList.add(new HisActivityInstanceVO(item));
            }
        }

        return Result.ok(hisVOList);
    }

    @Override
    public Result<List<SysDataProcessTaskVO>> queryHisTaskInstance(String processInstanceId) {
        List<SysDataProcessTaskVO> listVO = new ArrayList<>();
        List<SysDataProcessTask> taskList = sysDataProcessTaskService.listByProInsId(processInstanceId);
        if (CollectionUtils.isEmpty(taskList)) {
            return Result.ok(listVO);
        }
        // 查询转发(知会)的记录集合
        List<SysProcessNotify> notifyList = sysProcessNotifyService.getBaseMapper().selectList(new QueryWrapper<SysProcessNotify>()
                .eq(String.valueOf(SysProcessNotify.ColName.pro_ins_id), processInstanceId)
        );
        List<String> notifyUserIdList = notifyList.stream().map(SysProcessNotify::getNotifyUserId).collect(Collectors.toList());

        // 查询操作人的userId集合
        List<String> hisAssigneeList = taskList.stream().filter(a -> !Objects.isNull(a.getTaskAssignee()))
                .map(SysDataProcessTask::getTaskAssignee).collect(Collectors.toList());
        List<String> userIdList = new ArrayList<>();
        // 获取节点操作人的id集合
        hisAssigneeList.forEach(item -> {
            // 多个用逗号隔开，需要拆开
            if (item.contains(",")) {
                userIdList.addAll(Arrays.asList(item.split(",")));
            } else {
                userIdList.add(item);
            }
        });
        // 查询用户集合
        userIdList.addAll(notifyUserIdList);
        List<SysUser> userList = sysUserService.getBaseMapper().selectBatchIds(userIdList);


        // 数据处理,查询用户姓名等
        listVO = BeanUtils.entity2VO(taskList);
        listVO.forEach(item -> {
            SysUser user = userList.stream().filter(a -> a.getUserId().equals(item.getTaskAssignee())).findFirst().orElse(null);
            if (Objects.isNull(user)) {
                // 如果操作人是逗号隔开的话，另外处理
                item.setTaskAssigneeName(getOptUserName(item.getTaskAssignee(), userList));
            } else {
                item.setTaskAssigneeName(user.getName());
            }
            String taskSign = item.getTaskSign();
            if (StringUtils.isNotEmpty(taskSign)) {
                if (taskSign.length() == 32) {
                    // 处理签名图片，返回图片url
                    String url = iSysUploadsService.queryPictureUrlById(taskSign);
                    item.setTaskSign(url);
                }
            }

            // 获取节点通知的人名
            if(StringUtils.isNotEmpty(item.getTaskId())){
                List<SysProcessNotify> taskNotifyList = notifyList.stream().filter(a -> item.getTaskId().equals(a.getTaskId())).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(taskNotifyList)) {
                    List<String> taskNotifyUserIdList = taskNotifyList.stream().map(SysProcessNotify::getNotifyUserId).collect(Collectors.toList());
                    List<SysUser> intersectionUserList = userList.stream().filter(userItem -> taskNotifyUserIdList.contains(userItem.getUserId())).collect(Collectors.toList());
                    List<String> userNameList = intersectionUserList.stream().map(SysUser::getName).collect(Collectors.toList());
                    item.setNotifyName(StringUtils.join(userNameList, ","));
                }
            }
        });
        return Result.ok(listVO);
    }

    private String getOptUserName(String assignee, List<SysUser> userList) {
        if (StringUtils.isEmpty(assignee)) {
            return "";
        }
        List<String> userNameList = new ArrayList<>();
        if (assignee.contains(",")) {
            List<String> userIdList = Arrays.asList(assignee.split(","));
            userIdList.forEach(item -> {
                SysUser user = userList.stream().filter(a -> a.getUserId().equals(item)).findFirst().orElse(null);
                if (!Objects.isNull(user)) {
                    userNameList.add(user.getName());
                }
            });
        }
        return StringUtils.join(userNameList, ",");
    }

    @Override
    public boolean isFinished(String processInstanceId) {
        return historyService.createHistoricProcessInstanceQuery().finished()
                .processInstanceId(processInstanceId).count() > 0;
    }

    @Override
    public Result<String> getProcessDiagram(String processInstanceId, String processDefinitionId) {
        // 流程实例当前的节点，需要高亮显示
        List<String> currentActs = new ArrayList<>();
        if (StringUtils.isBlank(processDefinitionId) && StringUtils.isNotBlank(processInstanceId)) {
            // 如果流程已经结束，则得到结束节点
            if (this.isFinished(processInstanceId)) {
                HistoricProcessInstance pi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
                processDefinitionId = pi.getProcessDefinitionId();
            } else {// 如果流程没有结束，则取当前活动节点
                // 根据流程实例ID获得当前处于活动状态的ActivityId合集
                ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
                processDefinitionId = pi.getProcessDefinitionId();
            }
        }
        //获取流程图
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);

        if (StringUtils.isNotBlank(processInstanceId)) {
            currentActs = runtimeService.getActiveActivityIds(processInstanceId);
        } else {
            // 没有流程实例则默认第一个用户节点
            String firstUserTaskId = FlowableUtils.getFirstUserTaskId(bpmnModel);
            currentActs.add(firstUserTaskId);
        }
        //使用宋体
        String fontName = "宋体";
        InputStream inputStream = processEngineConfiguration.getProcessDiagramGenerator()
                .generateDiagram(bpmnModel, "png", currentActs, new ArrayList<>(), fontName, fontName, fontName, null, 1.0, true);

        try {
            byte[] bytes = IOUtils.toByteArray(inputStream);
            String encoded = Base64.getEncoder().encodeToString(bytes);
            return Result.ok("data:image/png;base64," + encoded);

           /* String img = new String(bytes, "UTF-8");
            String result = "";
            if (StringUtils.isNotBlank(img)) {
                result = FlowableUtils.svg2Base64(img);
            }
            return Result.ok(result);*/
        } catch (Exception e) {
            log.error("操作异常", e);
            return Result.fail("失败");
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
    }

    @Override
    public Result<ProcessImageVO> getProcessImage(String processInstanceId, String processDefinitionId) {
        ProcessImageVO processImageVO = new ProcessImageVO();
        String processDeploymentId = "";
        // 流程实例当前的节点，需要高亮显示
        List<String> currentActs = new ArrayList<>();
        // 流程实例历史的节点
        List<String> hisActList = new ArrayList<>();
        if (StringUtils.isNotBlank(processInstanceId)) {
            if (StringUtils.isBlank(processDefinitionId)) {
                SysDataProcess dataProcess = sysDataProcessService.getBaseMapper().selectOne(new QueryWrapper<SysDataProcess>()
                        .eq(String.valueOf(SysDataProcess.ColName.pro_ins_id), processInstanceId));
                if (Objects.isNull(dataProcess)) {
                    return Result.fail("没有查询到该流程实例");
                }
                processDeploymentId = dataProcess.getProcessDeploymentId();
            }
            //得到已经走过的节点的id集合
            List<HistoricActivityInstance> hisActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
                    .processInstanceId(processInstanceId)
                    .orderByHistoricActivityInstanceEndTime().desc()
                    .list();
            List<String> hisList = hisActivityInstanceList.stream().map(HistoricActivityInstance::getActivityId).collect(Collectors.toList());
            hisActList.addAll(hisList);
            if (!isFinished(processInstanceId)) {
                currentActs = runtimeService.getActiveActivityIds(processInstanceId);
            }
        } else if (StringUtils.isNotBlank(processDefinitionId)){
            // 查询流程定义
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(processDefinitionId).singleResult();
            processDeploymentId = processDefinition.getDeploymentId();
            //获取流程图
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
            if(Objects.isNull(bpmnModel)){
                return Result.fail("流程定义已被删除");
            }
            // 没有流程实例则默认第一个用户节点
            Collection<FlowElement> flowElements = bpmnModel.getMainProcess().getFlowElements();
            for (FlowElement flowElement : flowElements) {
                if (!Objects.isNull(flowElement) && flowElement instanceof StartEvent) {
                    hisActList.add(flowElement.getId());
                    // 开始节点的出口就是第一个用户节点
                    List<SequenceFlow> sequenceFlowList = ((StartEvent) flowElement).getOutgoingFlows();
                    if (CollectionUtils.isNotEmpty(sequenceFlowList)) {
                        hisActList.add(sequenceFlowList.get(0).getId());
                        currentActs.add(sequenceFlowList.get(0).getTargetRef());
                        break;
                    }
                }
            }
        }
        else {
            return Result.fail("参数错误，没有流程实例Id或定义Id");
        }
        hisActList = hisActList.stream().distinct().collect(Collectors.toList());

        processImageVO.setCurrentActList(currentActs);
        processImageVO.setHisActList(hisActList);

        String xml = repositoryMapper.queryEditorSource(processDeploymentId);
        processImageVO.setXml(xml);
        return Result.ok(processImageVO);
    }

    @Override
    public List<Task> queryDueTask(Date date) {
        // 1.查询当前还没过期的任务
        //List<Task> listTask = taskService.createTaskQuery().taskDueAfter(new Date()).list();

        // 2.查询当前已过期的任务
        //List<Task> listTask = taskService.createTaskQuery().taskDueBefore(new Date()).list();

        // 3.查询某个时间点过期的的任务，例如2019-12-29 16:21:07
        List<Task> listTask = taskService.createTaskQuery().taskDueDate(date).list();
        return listTask;
    }
}
